\documentclass[a4paper]{article}
\usepackage{xeCJK}
\setCJKmainfont{WenQuanYi Micro Hei} % 如果需要更换字体，可以自行调整
\usepackage[affil-it]{authblk}
\usepackage[backend=bibtex,style=numeric]{biblatex}
\usepackage{graphicx}
\usepackage{geometry}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{hyperref}   
\usepackage{fancyhdr}
\geometry{margin=1.5cm, vmargin={0pt,1cm}}
\setlength{\topmargin}{-1cm}
\setlength{\paperheight}{29.7cm}
\setlength{\textheight}{25.3cm}

\addbibresource{citation.bib}

\begin{document}

% =================================================
\title{Numerical Analysis Homework \# 3}
\author{王劼 (Wang Jie) \\ 3220100105 \thanks{Email: \texttt{2645443470@qq.com}}}
\affil{Department of Mathematics, Zhejiang University}
\date{Due date: \today}
\maketitle

\begin{abstract}
    本文设计文档详细描述了两个样条插值类的实现：分段多项式样条（Piecewise Polynomial Spline）和 B 样条（B-Spline）。这些插值方法广泛应用于数值分析中的数据平滑与逼近问题。本文将介绍程序的结构、功能接口、类之间的关系、数学背景及方程推导。
\end{abstract}

% ============================================
\section{概述}
本设计文档介绍了两个样条插值类的实现：分段多项式样条（Piecewise Polynomial Spline）和 B 样条（B-Spline）。这些插值方法适用于数值分析中常见的插值问题，特别是在数据平滑和逼近问题中。

本项目通过实现这两个类，提供了支持不同边界条件的插值方法，允许用户根据需要选择合适的样条插值方式。设计文档详细描述了程序的结构、类功能、类之间的关系、推导的方程组及相关数学理论。

% ============================================
\section{程序结构说明}
程序的基本结构包括以下几个部分：
\begin{itemize}
    \item \textbf{基类：Spline}：所有样条插值类的基类，定义了样条插值的公共接口。
    \item \textbf{PPFormSpline类}：实现基于分段多项式的样条插值。
    \item \textbf{BSpline类}：实现基于 B 样条的插值方法。
    \item \textbf{数学理论部分}：程序所涉及的插值方程推导及数学背景。
    \item \textbf{弦长计算部分}：计算数据点间的累积弦长并进行归一化，以便用于样条插值中的参数化。
\end{itemize}

% ============================================
\section{设计思路}
设计的核心思想是实现一个灵活且可扩展的样条插值系统，支持不同类型的边界条件（自然、周期、完全）。该设计的目标是提供一个通用的插值方法框架，能够处理多种插值类型和边界条件，同时保证插值结果的平滑性和高精度。

具体设计思路如下：
\begin{enumerate}
    \item \textbf{样条插值方法的抽象}：通过基类 \texttt{Spline} 提供统一的接口，使得不同插值方法（如分段多项式和 B 样条）具有统一的调用方式。
    \item \textbf{边界条件的灵活处理}：通过设计不同的边界条件计算方法，支持自然边界、周期边界和完全边界条件。
    \item \textbf{数学推导和数值计算}：采用数值求解方法计算样条系数，确保插值结果的准确性和计算效率。
    \item \textbf{弦长参数化}：通过计算数据点之间的欧几里得距离并进行累积，最后对其归一化，以确保插值过程中的参数平滑。
\end{enumerate}

% ============================================
\section{类的功能接口}
程序包括以下主要类：\texttt{Spline}（基类）、\texttt{PPFormSpline}（分段多项式样条）和 \texttt{BSpline}（B 样条）。

\subsection{Spline类}
\texttt{Spline} 是所有样条插值类的基类，定义了样条插值的基本结构，并声明了纯虚函数 \texttt{SplineReturn(double x)}，用于计算给定点 \texttt{x} 的插值结果。

\subsubsection{成员变量}
\begin{itemize}
    \item \texttt{std::vector<double> node}：存储样条的节点位置。
\end{itemize}

\subsubsection{成员函数}
\begin{itemize}
    \item \texttt{virtual double SplineReturn(double x) = 0;}：纯虚函数，计算给定 \texttt{x} 的插值值。所有子类必须实现该方法。
\end{itemize}

\subsection{PPFormSpline类}
\texttt{PPFormSpline} 类实现了基于分段多项式的样条插值方法，支持不同类型的边界条件。该类通过计算差商来求解样条系数，并根据边界条件进行调整。

\subsubsection{成员变量}
\begin{itemize}
    \item \texttt{std::vector<double> first\_derivatives}：存储每个节点的一阶导数，用于分段多项式的构造。
    \item \texttt{std::vector<double> y}：存储每个节点的函数值。
    \item \texttt{std::vector<std::vector<double>> dividedDifferences}：存储差商，用于插值多项式的计算。
\end{itemize}

\subsubsection{成员函数}
\begin{itemize}
    \item \texttt{void computeNaturalBoundary()}：计算自然边界条件，即两端的二阶导数为零。
    \item \texttt{void computePeriodicBoundary()}：计算周期边界条件，即样条在两端是周期性的。
    \item \texttt{void computeCompleteBoundary()}：计算完全边界条件，允许指定边界的一阶导数。
    \item \texttt{void computeFirstDerivatives()}：根据边界条件计算每个节点的一阶导数。
    \item \texttt{double SplineReturn(double x)}：根据计算得到的导数和节点，使用分段多项式方法计算给定 \texttt{x} 的插值值。
\end{itemize}

\subsection{BSpline类}
\texttt{BSpline} 类实现了基于 B 样条的插值方法，支持不同的边界条件。B 样条通过一组基函数来构造样条曲线，基函数的选择由样条的度数（\texttt{degree}）决定。

\subsubsection{成员变量}
\begin{itemize}
    \item \texttt{int degree}：样条的度数，控制 B 样条的阶数。
    \item \texttt{std::vector<double> points}：存储样条的节点位置。
    \item \texttt{std::vector<double> a}：存储计算得到的系数。
\end{itemize}

\subsubsection{成员函数}
\begin{itemize}
    \item \texttt{void computeNaturalBoundary()}：计算自然边界条件。
    \item \texttt{void computePeriodicBoundary()}：计算周期边界条件。
    \item \texttt{void computeCompleteBoundary()}：计算完全边界条件。
    \item \texttt{void compute\_a()}：计算 B 样条的系数 \texttt{a}，并根据边界条件选择合适的边界类型。
    \item \texttt{double B(int i, double t)}：计算 B 样条基函数。
    \item \texttt{double B\_derivative(int i, double t)}：计算 B 样条基函数的导数。
\end{itemize}

% ============================================
\subsection{弦长计算及归一化}
为了在样条插值中应用累积弦长作为参数化，我们首先计算数据点间的欧几里得距离，并通过这些距离累积得到累积弦长向量。最后，对累积弦长进行归一化，使其范围位于 \([0, 1]\)，从而提供适用于样条插值的平滑参数。

\subsection{函数接口}
\begin{itemize}
    \item \texttt{double euclideanDistance(double x1, double y1, double x2, double y2)}：计算两个二维点之间的欧几里得距离。
    \item \texttt{void calculateCumulativeChordLengths(const std::vector<std::pair<double, double>>\& points)}: 根据给定的数据点，计算并归一化累积弦长。
    \item \texttt{std::vector<double> normalizedChordLengths}：归一化后的弦长值，可用于插值过程中的参数化。
\end{itemize}

% ============================================
\section{类之间的关系}
\begin{itemize}
    \item \texttt{Spline} 是所有插值类的基类，定义了样条插值的公共接口。
    \item \texttt{PPFormSpline} 和 \texttt{BSpline} 都继承自 \texttt{Spline} 类，分别实现了分段多项式样条和 B 样条的具体插值方法。
    \item 通过继承机制，\texttt{PPFormSpline} 和 \texttt{BSpline} 都需要实现 \texttt{SplineReturn} 方法，这样可以通过统一的接口来调用不同类型的插值方法。
    \item \texttt{PPFormSpline} 和 \texttt{BSpline} 类都可以通过弦长计算部分的接口来进行参数化，从而使用样条插值算法在弦长参数空间内进行插值。
\end{itemize}

% ============================================
\section{数学推导与理论}
本节介绍样条插值的数学理论，重点讲解如何通过给定的节点和边界条件求解样条系数，使得样条在节点上插值精确并满足边界条件。

% ============================================
\section{总结}
本程序实现了基于分段多项式和 B 样条的插值方法，支持不同的边界条件类型，并结合了弦长计算的参数化方法。通过合理的类设计和数学推导，本系统为解决高精度插值问题提供了高效且可靠的解决方案。

% ============================================
\section*{\center{\normalsize{Acknowledgement}}}
None.

\printbibliography

\end{document}
